import { compileToFunction } from "./compiler/index";
import { callHook, mountComponent } from "./lifecycle";
import { initState } from "./state";
import { mergeOptions } from "./utils";

export default function initMixin(Vue) {
    Vue.prototype._init = function (options) {
        const vm = this;
        // this.$options = options;//所有后续的扩展方法都有一个$option选项可以获取用户的所有选
        vm.$options = mergeOptions(this.constructor.options, options);
        callHook(vm, 'beforeCreate');
        //对于实例的数据源 props data methods computed watch
        initState(vm);
        //vue中会判断如果是$开头的属性不会被变成响应式数据
        //状态初始化完毕后需要进行页面挂载
        if (vm.$options.el) {//el属性和直接调用$mount是一样的
            vm.$mount(vm.$options.el);
        }
    }

    Vue.prototype.$mount = function (el) {
        const vm = this;
        el = document.querySelector(el);
        let options = vm.$options;

        if (!options.render) {
            let template;
            if (!options.template && el) {//没有写模版 但是写了el
                template = el.outerHTML
            } else {
                    template = options.template;
            }
            //将template变成render函数;
            //创建render函数->虚拟dom->渲染真实dom
            //写了template就用写了的template
            if (template) {//只要有模版就挂载
                const render = compileToFunction(template);//开始编译
                options.render = render;
            }
        }
        mountComponent(vm, el) // 一定存在了
    }

    //diff算法 主要是两个虚拟节点的比对，我们需要根据模版渲染出一个render函数，render函数可以返回一个虚拟节点，数据更新了重新调用render函数，可以再返回一个虚拟节点
}